第20章 Tailwind CSS 实用指南
实用优先的 CSS 框架,快速构建现代 UI
作者:zyyc-0336 | 日期:2026-06-12
本文是前端学习路径第20章(阶段五:外围生态)
上一章:19. 部署与上线 | 下一章:21. 使用第三方React组件
阶段简介:外围生态
前四阶段我们掌握了 HTML/CSS/JS 基础、React 框架、Next.js 全栈开发。从本章开始进入第五阶段:外围生态——学习 Tailwind CSS 原子化样式、第三方组件集成、数据库对接、主题切换等实战技能,让你的项目从"能跑"进化到"好用又好看"。
前四阶段我们掌握了 HTML/CSS/JS 基础、React 框架、Next.js 全栈开发。从本章开始进入第五阶段:外围生态——学习 Tailwind CSS 原子化样式、第三方组件集成、数据库对接、主题切换等实战技能,让你的项目从"能跑"进化到"好用又好看"。
一句话总结:Tailwind 让你不用写 CSS 文件,直接在 HTML 的 class 里用工具类拼出所有样式。
学习路径建议
原子化 CSS 概念(为什么用 Tailwind)
↓
在 Next.js 中安装配置
↓
常用工具类(文字/背景/间距/圆角/阴影)
↓
响应式前缀(sm:/md:/lg:)
↓
暗色模式(dark:)
↓
自定义主题
↓
实战:用 Tailwind 重写导航栏和文章卡片20.1 什么是原子化 CSS
概念解释
传统 CSS:给每个组件写一套专属样式。
CSS
/* 传统写法 */
.card {
padding: 16px;
background: white;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}原子化 CSS:把样式拆成最小粒度的"工具类",直接组合使用。
JSX
<!-- Tailwind 写法:不用写 CSS 文件 -->
<div class="p-4 bg-white rounded-lg shadow-md">
内容
</div>两种方式对比
| 对比项 | 传统 CSS | Tailwind 原子化 |
|---|---|---|
| 样式写在哪 | 单独的 .css 文件 | 直接写在 class 里 |
| 命名 | 自己起类名(.card, .btn) | 用官方工具类(p-4, bg-white) |
| 复用方式 | 复用类名 | 复用组合(或抽组件) |
| 文件体积 | 可能越来越大 | 自动删除未使用的类,很小 |
| 上手难度 | 低 | 需要记工具类名 |
⚠️ "class 那么长,不会很乱吗?" 刚开始确实觉得长,但用熟了比写 CSS 快很多。而且组件化后,样式跟结构在一起,修改时不用 CSS 和 HTML 来回跳。
20.2 在 Next.js 中安装 Tailwind
安装步骤
Bash
# 第 1 步:安装依赖
npm install -D tailwindcss @tailwindcss/postcss postcss
# 第 2 步:初始化配置
npx tailwindcss init配置 postcss.config.mjs
JS
// postcss.config.mjs
const config = {
plugins: {
"@tailwindcss/postcss": {},
},
};
export default config;配置全局 CSS
CSS
/* app/globals.css */
@import "tailwindcss";在 layout.tsx 中引入
TSX
// app/layout.tsx
import "./globals.css";
export default function RootLayout({ children }) {
return (
<html lang="zh">
<body>{children}</body>
</html>
);
}验证安装
TSX
// app/page.tsx
export default function Home() {
return (
<h1 className="text-3xl font-bold text-blue-600 p-8">
Tailwind 安装成功!
</h1>
);
}看到蓝色大标题就说明成功了。
⚠️ 忘记引入 globals.css:Tailwind 不会生效,页面没有样式。
⚠️ 用 className 而不是 class:在 JSX 中必须写
⚠️ 用 className 而不是 class:在 JSX 中必须写
className。
20.3 常用工具类速查
20.3.1 文字相关
| 作用 | 类名 | 等价 CSS |
|---|---|---|
| 字号 | text-sm | font-size: 0.875rem |
| 字号 | text-base | font-size: 1rem |
| 字号 | text-lg | font-size: 1.125rem |
| 字号 | text-xl | font-size: 1.25rem |
| 字号 | text-2xl | font-size: 1.5rem |
| 字号 | text-3xl | font-size: 1.875rem |
| 字重 | font-normal | font-weight: 400 |
| 字重 | font-bold | font-weight: 700 |
| 颜色 | text-red-500 | color: #ef4444 |
| 颜色 | text-gray-600 | color: #4b5563 |
| 对齐 | text-center | text-align: center |
20.3.2 背景相关
| 作用 | 类名 | 等价 CSS |
|---|---|---|
| 背景色 | bg-white | background: #fff |
| 背景色 | bg-blue-500 | background: #3b82f6 |
| 背景色 | bg-gray-100 | background: #f3f4f6 |
| 渐变 | bg-gradient-to-r | 向右渐变 |
20.3.3 间距(padding / margin)
Tailwind 的间距用数字表示,1 = 0.25rem = 4px。
| 类名 | 等价 CSS | 实际像素 |
|---|---|---|
p-1 | padding: 0.25rem | 4px |
p-2 | padding: 0.5rem | 8px |
p-4 | padding: 1rem | 16px |
p-8 | padding: 2rem | 32px |
m-4 | margin: 1rem | 16px |
mx-auto | margin: 0 auto | 水平居中 |
mt-4 | margin-top: 1rem | 16px |
gap-4 | gap: 1rem | 16px(flex/grid) |
方向前缀:t(top)、b(bottom)、l(left)、r(right)、x(左右)、y(上下)
20.3.4 圆角与阴影
| 作用 | 类名 | 等价 CSS |
|---|---|---|
| 小圆角 | rounded | border-radius: 0.25rem |
| 中圆角 | rounded-lg | border-radius: 0.5rem |
| 大圆角 | rounded-xl | border-radius: 0.75rem |
| 全圆角 | rounded-full | border-radius: 9999px |
| 阴影 | shadow-sm | 小阴影 |
| 阴影 | shadow-md | 中阴影 |
| 阴影 | shadow-lg | 大阴影 |
完整示例:一个简单卡片
JSX
export default function Card() {
return (
<div className="p-6 bg-white rounded-xl shadow-md">
<h2 className="text-xl font-bold text-gray-800">
卡片标题
</h2>
<p className="mt-2 text-gray-600">
这是卡片内容,用了 Tailwind 工具类来设置样式。
</p>
</div>
);
}逐行讲解
| 行 | 类名 | 作用 |
|---|---|---|
| 容器 | p-6 bg-white rounded-xl shadow-md | 内边距24px、白色背景、大圆角、中阴影 |
| 标题 | text-xl font-bold text-gray-800 | 大字号、加粗、深灰色 |
| 正文 | mt-2 text-gray-600 | 上间距8px、浅灰色 |
⚠️ 间距单位记混:
⚠️ 颜色格式:Tailwind 用
p-4 是 16px,不是 4px。记住 数字 × 4 = 像素值。⚠️ 颜色格式:Tailwind 用
颜色名-色阶 格式,如 blue-500,色阶从 50(最浅)到 950(最深)。
20.4 响应式设计(sm:/md:/lg:)
概念解释
Tailwind 的响应式设计用前缀来控制不同屏幕宽度下的样式,默认断点:
| 前缀 | 最小宽度 | 常见设备 |
|---|---|---|
| (无前缀) | 0px | 手机(默认样式) |
sm: | 640px | 大手机/小平板 |
md: | 768px | 平板 |
lg: | 1024px | 笔记本 |
xl: | 1280px | 桌面显示器 |
语法
className="默认样式 sm:小屏样式 md:中屏样式 lg:大屏样式"先写默认(手机优先),再逐级覆盖。
完整示例:响应式网格
JSX
export default function ResponsiveGrid() {
return (
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4 p-4">
<div className="bg-blue-200 p-4 rounded-lg">卡片 1</div>
<div className="bg-blue-300 p-4 rounded-lg">卡片 2</div>
<div className="bg-blue-400 p-4 rounded-lg">卡片 3</div>
<div className="bg-blue-500 p-4 rounded-lg text-white">卡片 4</div>
</div>
);
}逐行讲解
| 类名 | 作用 |
|---|---|
grid | 启用网格布局 |
grid-cols-1 | 默认手机:1 列 |
sm:grid-cols-2 | 640px+:2 列 |
md:grid-cols-3 | 768px+:3 列 |
lg:grid-cols-4 | 1024px+:4 列 |
gap-4 | 卡片间距 16px |
p-4 | 整体内边距 16px |
⚠️ 顺序写反:Tailwind 断点是 min-width,所以默认样式放前面,大屏覆盖放后面。如果写
正确写法:
lg:text-sm text-xl,在大屏上会是 text-xl(因为后面的无前缀类覆盖了前面的)。正确写法:
text-xl lg:text-3xl(手机大字,电脑更大)
20.5 暗色模式(dark:)
概念解释
Tailwind 内置暗色模式支持,用 dark: 前缀定义暗色主题下的样式。
配置方式
在 tailwind.config.js 中设置策略:
JS
// tailwind.config.js(Tailwind v4 可通过 CSS 变量配置)
// 这里演示 v3 的配置方式
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: "class", // 用 class 切换暗色模式
content: ["./app/**/*.{js,ts,jsx,tsx}"],
theme: { extend: {} },
plugins: [],
};darkMode: "class"表示在<html>标签上加dark类来激活暗色模式。
语法
className="亮色样式 dark:暗色样式"完整示例:支持暗色模式的卡片
JSX
export default function DarkCard() {
return (
<div className="p-6 bg-white dark:bg-gray-800 rounded-xl shadow-md">
<h2 className="text-xl font-bold text-gray-800 dark:text-white">
标题
</h2>
<p className="mt-2 text-gray-600 dark:text-gray-300">
内容
</p>
</div>
);
}逐行讲解
| 类名 | 亮色效果 | 暗色效果 |
|---|---|---|
bg-white dark:bg-gray-800 | 白色背景 | 深灰背景 |
text-gray-800 dark:text-white | 深灰文字 | 白色文字 |
text-gray-600 dark:text-gray-300 | 灰色文字 | 浅灰文字 |
切换暗色模式的 JS 代码
JSX
// 一个简单的切换按钮组件
"use client";
import { useState, useEffect } from "react";
export default function ThemeToggle() {
const [dark, setDark] = useState(false);
useEffect(() => {
document.documentElement.classList.toggle("dark", dark);
}, [dark]);
return (
<button
onClick={() => setDark(!dark)}
className="px-4 py-2 rounded-lg bg-gray-200 dark:bg-gray-700
text-gray-800 dark:text-white"
>
{dark ? "☀️ 亮色模式" : "🌙 暗色模式"}
</button>
);
}
⚠️ 忘记配置 darkMode:不配置的话
⚠️ 暗色样式和亮色样式冲突:不要同时写
dark: 前缀不生效。⚠️ 暗色样式和亮色样式冲突:不要同时写
bg-white bg-gray-800,必须用 dark: 前缀区分。
20.6 自定义主题
概念解释
当默认颜色、间距不够用时,可以在配置中扩展主题。
方式一:tailwind.config.js 扩展(v3)
JS
// tailwind.config.js
module.exports = {
content: ["./app/**/*.{js,ts,jsx,tsx}"],
theme: {
extend: {
colors: {
brand: "#6366f1", // 自定义品牌色
"brand-light": "#818cf8",
},
spacing: {
"128": "32rem", // 自定义间距
},
fontFamily: {
custom: ["Noto Sans SC", "sans-serif"],
},
},
},
};使用方式:
JSX
<div className="bg-brand text-brand-light font-custom p-128">
自定义主题
</div>方式二:CSS 变量(v4 推荐)
CSS
/* globals.css */
@import "tailwindcss";
@theme {
--color-brand: #6366f1;
--color-brand-light: #818cf8;
--font-family-custom: "Noto Sans SC", sans-serif;
}使用方式和上面一样:bg-brand、font-custom。
常用自定义项
| 要自定义的 | 配置 key | 使用类名 |
|---|---|---|
| 颜色 | colors.brand | bg-brand, text-brand |
| 字体 | fontFamily.custom | font-custom |
| 间距 | spacing.128 | p-128, m-128 |
| 圆角 | borderRadius.2xl | rounded-2xl |
⚠️ v3 和 v4 配置方式不同:v3 用
⚠️ 修改配置后需要重启开发服务器:否则新主题不生效。
tailwind.config.js,v4 推荐用 CSS @theme。⚠️ 修改配置后需要重启开发服务器:否则新主题不生效。
20.7 实战:重写导航栏和文章卡片
20.7.1 用 Tailwind 写导航栏
TSX
// components/Navbar.tsx
"use client";
import Link from "next/link";
export default function Navbar() {
return (
<nav className="bg-white dark:bg-gray-900 shadow-md sticky top-0 z-50">
<div className="max-w-6xl mx-auto px-4 py-3 flex items-center justify-between">
{/* Logo */}
<Link href="/" className="text-xl font-bold text-blue-600 dark:text-blue-400">
MyBlog
</Link>
{/* 导航链接 */}
<div className="flex gap-6">
<Link href="/" className="text-gray-700 dark:text-gray-300 hover:text-blue-500 transition">
首页
</Link>
<Link href="/about" className="text-gray-700 dark:text-gray-300 hover:text-blue-500 transition">
关于
</Link>
<Link href="/blog" className="text-gray-700 dark:text-gray-300 hover:text-blue-500 transition">
博客
</Link>
</div>
</div>
</nav>
);
}逐行讲解
| 类名 | 作用 |
|---|---|
bg-white dark:bg-gray-900 | 亮色白底,暗色深灰底 |
shadow-md | 底部阴影 |
sticky top-0 | 固定在页面顶部 |
z-50 | 层级最高,不被遮挡 |
max-w-6xl mx-auto | 最大宽度 1152px,水平居中 |
px-4 py-3 | 左右 padding 16px,上下 12px |
flex items-center justify-between | 弹性布局,垂直居中,两端对齐 |
gap-6 | 链接间距 24px |
hover:text-blue-500 | 悬停变蓝 |
transition | 颜色过渡动画 |
20.7.2 用 Tailwind 写文章卡片
TSX
// components/ArticleCard.tsx
interface ArticleCardProps {
title: string;
summary: string;
date: string;
tag: string;
}
export default function ArticleCard({ title, summary, date, tag }: ArticleCardProps) {
return (
<article className="bg-white dark:bg-gray-800 rounded-xl shadow-md
hover:shadow-lg transition-shadow duration-300 overflow-hidden">
{/* 标签和日期 */}
<div className="px-6 pt-5 flex items-center justify-between">
<span className="text-xs font-medium px-3 py-1 rounded-full
bg-blue-100 dark:bg-blue-900 text-blue-700 dark:text-blue-300">
{tag}
</span>
<time className="text-sm text-gray-400">{date}</time>
</div>
{/* 标题和摘要 */}
<div className="px-6 py-4">
<h3 className="text-lg font-bold text-gray-800 dark:text-white
hover:text-blue-600 dark:hover:text-blue-400 cursor-pointer">
{title}
</h3>
<p className="mt-2 text-sm text-gray-500 dark:text-gray-400 line-clamp-2">
{summary}
</p>
</div>
{/* 底部按钮 */}
<div className="px-6 pb-5">
<button className="text-sm text-blue-600 dark:text-blue-400
hover:underline font-medium">
阅读全文 →
</button>
</div>
</article>
);
}使用示例
TSX
// app/page.tsx
import Navbar from "@/components/Navbar";
import ArticleCard from "@/components/ArticleCard";
export default function Home() {
return (
<div className="min-h-screen bg-gray-50 dark:bg-gray-900">
<Navbar />
<main className="max-w-6xl mx-auto px-4 py-8">
<h1 className="text-3xl font-bold text-gray-800 dark:text-white mb-8">
最新文章
</h1>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<ArticleCard
title="Next.js 入门教程"
summary="从零开始学习 Next.js,了解 App Router、数据获取和部署。"
date="2026-06-12"
tag="Next.js"
/>
<ArticleCard
title="Tailwind CSS 实用指南"
summary="掌握原子化 CSS 的核心概念和常用工具类。"
date="2026-06-12"
tag="CSS"
/>
<ArticleCard
title="React Hooks 深入理解"
summary="useState、useEffect、useRef 等核心 Hooks 的原理和用法。"
date="2026-06-10"
tag="React"
/>
</div>
</main>
</div>
);
}
⚠️
⚠️
line-clamp-2 不生效:需要确认 Tailwind 版本支持,或手动添加 CSS。⚠️
overflow-hidden 别忘了:卡片圆角 + 阴影时,不加这个可能导致内容溢出圆角。
20.8 本章复盘
核心知识点总结
| 知识点 | 关键内容 | 一句话记忆 |
|---|---|---|
| 原子化 CSS | 用最小粒度的类名组合样式 | 不写 CSS 文件,样式写在 class 里 |
| 安装配置 | npm install tailwindcss + @import "tailwindcss" | 装包 → 配置 → 引入全局 CSS |
| 文字类 | text-xl, font-bold, text-gray-600 | text-大小 font-粗细 text-颜色 |
| 背景类 | bg-white, bg-blue-500 | bg-颜色名-色阶 |
| 间距类 | p-4, m-2, gap-4 | 数字×4=像素 |
| 圆角阴影 | rounded-lg, shadow-md | rounded-大小, shadow-大小 |
| 响应式 | sm:, md:, lg: | 手机优先,前缀覆盖大屏 |
| 暗色模式 | dark:bg-gray-800 | dark: 前缀 + class 模式 |
| 自定义主题 | @theme 或 tailwind.config.js | extend 里加自定义颜色/字体 |
新手速记口诀
间距数字乘以四,颜色名字带色阶
响应前缀 sm/md/lg,暗色 dark 冒号写前面
手机优先写默认,大屏覆盖写后面常见错误速查
| 错误现象 | 原因 | 解决方案 |
|---|---|---|
| 样式完全不生效 | 忘记引入 globals.css | 检查 @import "tailwindcss" |
| JSX 中 class 报错 | 应该用 className | class → className |
| 响应式不生效 | 断点顺序写反 | 默认样式在前,大屏覆盖在后 |
| 暗色模式不生效 | 没配置 darkMode | 配置 darkMode: "class" |
| 自定义颜色无效 | 修改配置后没重启 | 重启 npm run dev |
| 间距值不对 | 记错换算关系 | p-4 = 16px,不是 4px |
本章复盘——Tailwind CSS 核心要点
| 要点 | 说明 |
|---|---|
| 原子化 CSS | 每个类名只做一件事,组合使用 |
| 响应式 | sm/md/lg 前缀,手机优先设计 |
| 暗色模式 | dark: 前缀,class 或 media 策略 |
| 自定义主题 | tailwind.config.js 扩展颜色/字体 |
下一章预告(第21章):我们将学习使用第三方 React 组件——站在巨人的肩膀上,用 npm 安装现成的轮子(Markdown 渲染器、音视频播放器等),快速给博客添加强大功能。
本文档由 zyyc-0336 编写,最后更新:2026-06-14